在資料工程的世界裡,要做好資料治理、管控資料品質,確保數據的「新鮮度」是非常重要的。
為了管理數據的新鮮度,dbt 提供了 freshness checks 功能(如文件),幫助我們監控資料表的更新狀態。然而,這個功能在某些情境下的設計與操作方式,跟我原先的期望有所不同。來看看具體的落差吧!
我以為的:
在運行資料模型之前,加上 dbt source freshness
就可以檢查所有要更新的資料來源是否是最新狀態。這個方法可能是檢查該原始資料表最後更新的時間。
實際情況:
根據 dbt 官方文件,dbt source freshness
讓我們可以檢查資料來源的最新狀態是否符合期待。而這個檢查的方法,是透過選定資料表中的一個時間戳記欄位來進行檢查,在該資料表下設定你要檢查的欄位(例如:created_at_tw),dbt 會檢查該欄位中的最新值,將其與當前時間進行比較。我們可以設定 warn_after 與 error_after,設定不同的時間區間,分別進行提醒與報錯,譬如說我要設定一小時沒有資料更新則提醒我,但若一整天都沒有資料更新,就要直接報錯,並且中斷後續的 pipeline,就可以這樣設定:
tables:
- name: orders
freshness:
warn_after: {count: 1, period: hour}
error_after: {count: 24, period: hour}
loaded_at_field: last_updated_at
在 dbt 的設計中,我們並非基於表格的更新時間,而是依照使用者紀錄的最新使用時間來作為數據新鮮度的判斷依據。這導致了一個潛在問題:即使表格已經更新,若沒有新的資料進來,dbt 依然會判定該表格的數據過期。
我們原本想說肯定是有人會使用的吧,不可能有什麼功能一整天都沒有記錄的吧(立 flag)。結果就在某次長假中,平台上某個老師帶領學生使用的功能,一整天都沒有半個人使用,害我假期放到一半還要來看 pipeline 發生了什麼問題(真是的,怎麼放假了就不好好學習呢(誤XD))
除了上述問題,dbt source freshness
的配置也變得比想像中更為複雜。原先我以為只要加上這行指令,就可以高枕無憂了,但由於他要選定時間欄位,並設定容許的更新時間頻率,因此需要每一張表各自進行設定。
這個設定可以針對不同單位大小來進行,譬如針對同一個資料集的所有資料表,或是單一資料表,就如同 CSS 的設定,更小顆粒度的設定為優先,我們可以先針對整個資料集做設定,而若哪一張表格有不同的更新頻率,我們再針對它做特例處理。
身為認真的讀者,你可能會想說:「這時候,之前說到的「統一欄位命名」就發揮出它的功效了!全部的時間欄位都有一致的命名方式。」
不錯,聽起來挺不錯的,但實作時會發現,這邊的檢查是針對原始資料做檢查,資料表的命名不是 dbt 的轉換能決定的呀~~~
因此蠻多時候需要一張一張資料表慢慢設定,欄位名稱不同,特別是當每張資料表更新的頻率也不太相同時,更容易出現差錯,沒有想像中這麼容易呢。